import logging
import os, pdb
import time, json
from pprint import pprint
from django.conf import settings
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from django.http import JsonResponse
from django.db.models import Q
from conf.sysConfig import config
from software.utils import fileStore
from software.models import Software, SoftwareType, SoftwareVersion, SoftwareData, SoftwareGroup
from order.models import SoftwareOrder
from storehouse.models import Storehouse
from user import dataCheck as da
from user.dataCheck import DataCheck
from software.utils.fileStore import tarSaveToDataBase
from user.models import Company, FileStore
from order.views.createOrder import createOrder
from software.views.view_download import download
from software.views.view_software import tolist

datacheck = DataCheck()
tmpDir = os.path.join(config["dataDir"], config["tmpDir"])
logger_request = logging.getLogger("django.request")


# 获取组列表
def groupList(request, *args, **kwargs):
    """
       url: '/software/grouplist/',
        method: 'post',
        inputData: {
            token: data.token,//用户密钥
            page: data.page,//当前页
            maxItem: data.maxItem,//每页个数
            softwareGroup: data.softwareGroup,//管理人员(使用人员)-0:(包括所有) 1：已删除
        },
        resData: {
            'code': null, // 标志返回状态、0：成功 1：失败
            'msg': null, // 返回消息
            'totalNum': null,//检索到总条数
            'groupList': [{
                'groupName': null,//服务名称
                'groupId': null,//组id
                'userName': null,//编组用户
                'uploadTime': null,//组上传时间
                'groupDetail': null,//组描述
                'groupType': null,//编排方式
                'isOnline'： null
                'groupSoftware': [{//编组包含的软件
                    'softwareId': null,//软件id
                    'softwareName': null,//软件名称
                    'softwareDetail': null,//最新版本的描述
                    'version': [{'versionName': null, 'versionId': null, 'isOnline': 0,1}],//编组时每个软件选择的版本
                }]
            }]
        }
        }
    """
    form = request.checkForm
    requestParam = form.cleaned_data
    logger_request.info(requestParam)

    user = datacheck.getUser(requestParam["token"])
    filterDict = {}
    if user.userType == '2' or user.userType == '3':
        if requestParam['softwareGroup'] == '0':
            filterDict['isActive'] = 1
        elif requestParam['softwareGroup'] == '1':
            filterDict['isActive'] = 0
        else:
            data = {
                'code': 1,
                'msg': 'softwareGroup Error',
            }
            logger_request.info(data)
            return JsonResponse(data)
    else:
        data = {
            'code': 1,
            'msg': 'userType Error',
        }
        logger_request.info(data)
        return JsonResponse(data)
    if user.userType == '3':
        # todo 暂时可浏览可下载
        # filterDict['isDownload'] = user.company
        filterDict['isBrowse'] = user.company
    elif user.userType == '2':
        filterDict['groupUserType'] = '2'
    else:
        pass
    if user.userType == '2':
        softwareGroup = SoftwareGroup.objects.filter(**filterDict).order_by('-uploadTime')
    else:
        softwareGroup = SoftwareGroup.objects.filter(**filterDict).order_by('-uploadTime').filter(
            Q(user=user) | Q(groupUserType='2', isOnline=True))
    if softwareGroup.exists():
        totalNum = len(softwareGroup)
        result = softwareGroup[min(totalNum, (requestParam['page'] - 1) * requestParam['maxItem']): min(totalNum,
                                                                                                        requestParam[
                                                                                                            'page'] *
                                                                                                        requestParam[
                                                                                                            'maxItem'])]
        groupList = []
        # 临时存储
        for groupItem in result:
            softwareDict = {}
            for softwareVersion in groupItem.software.all():
                if softwareVersion.software.id not in softwareDict.keys():
                    tempVersion = []
                    versionList = {
                        'versionId': softwareVersion.id,
                        'versionName': softwareVersion.version,
                        'isOnline': softwareVersion.isOnline
                    }
                    tempVersion.append(versionList)
                    softwareItem = {
                        'softwareId': softwareVersion.software.id,
                        'softwareName': softwareVersion.softwareName,
                        'softwareDetail': softwareVersion.updateDetails,
                        'currentVersionDesc': softwareVersion.currentVersionDesc,
                        # 'downloadurl': download(softwareVersion.file.fileName, 'file', softwareVersion.file.filePath)[1],
                        'softList': tolist(softwareVersion.file.all(), False),
                        'version': tempVersion
                    }
                    softwareDict[softwareVersion.software.id] = softwareItem
                else:
                    versionList = {
                        'versionId': softwareVersion.id,
                        'versionName': softwareVersion.version,
                        'isOnline': softwareVersion.isOnline
                    }
                    softwareDict[softwareVersion.software.id]['version'].append(versionList)
            groupSoftware = []
            for i in softwareDict.keys():
                groupSoftware.append(softwareDict[i])
            item = {
                'groupName': groupItem.groupName,
                'groupId': groupItem.id,
                'userName': groupItem.user.name,
                'uploadTime': groupItem.uploadTime.strftime('%Y-%m-%d %H:%M:%S'),
                'groupDetail': groupItem.describe,
                'groupType': groupItem.groupType,
                'isOnline': groupItem.isOnline,
                'groupSoftware': groupSoftware
            }
            groupList.append(item)

        data = {
            'code': 0,
            'msg': 'success',
            'totalNum': totalNum,
            'groupList': groupList,
        }
        logger_request.info(data)
        return JsonResponse(data)
    else:
        data = {
            'code': 0,
            'msg': 'success',
            'totalNum': 0,
            'groupList': []
        }
        logger_request.info(data)
        return JsonResponse(data)


# 软件筛选、搜索
def groupSearch(request, *args, **kwargs):
    """
        url: '/software/groupscreen/',
        method: 'post',
        inputData: {
            token: data.token,//用户密钥
            page: data.page,//当前页
            maxItem: data.maxItem,//每页个数
            softwareGroup: data.softwareGroup,//管理人员（使用人员）-0:(包括所有) 1：已删除
            category: data.category,//0：软件自由编排，1：能力分组，2：能力预案，3用户订阅
            groupName: data.groupName,//搜索服务名称

        },
        resData: {
            'code': null, // 标志返回状态、0：成功 1：失败
            'msg': null, // 返回消息
            'totalNum': null,//检索到总条数
            'groupList': [{
                'groupName': null,//服务名称
                'groupId': null,//组id
                'userName': null,//编组用户
                'uploadTime': null,//组上传时间
                'groupDetail': null,//组描述
                'groupType': null,//编排方式
                'isOnline'： null
                'groupSoftware': [{//编组包含的软件
                    'softwareId': null,//软件id
                    'softwareName': null,//软件名称
                    'softwareDetail': null,//最新版本的描述
                    'version': [{'versionName': null, 'versionId': null, 'isOnline': 0,1}],//编组时每个软件选择的版本
                }]
            }]
        }
        }
        """
    form = request.checkForm
    requestParam = form.cleaned_data
    logger_request.info(requestParam)

    user = datacheck.getUser(requestParam["token"])
    filterDict = {}
    if user.userType == '2' or user.userType == '3':
        if requestParam['softwareGroup'] == '0':
            pass
        elif requestParam['softwareGroup'] == '1':
            filterDict['isActive'] = 0
        else:
            data = {
                'code': 1,
                'msg': 'softwareGroup Error',
            }
            logger_request.info(data)
            return JsonResponse(data)
        if requestParam['category'] != '':
            filterDict['groupType'] = requestParam['category']
        if requestParam['groupName'] != '':
            filterDict['groupName__icontains'] = requestParam['groupName']
    else:
        data = {
            'code': 1,
            'msg': 'userType Error',
        }
        logger_request.info(data)
        return JsonResponse(data)
    if user.userType == '3':
        # todo 暂时可浏览可下载
        # filterDict['isDownload'] = user.company
        filterDict['isBrowse'] = user.company
    elif user.userType == '2':
        filterDict['groupUserType'] = '2'
    else:
        pass
    if user.userType == '2':
        softwareGroup = SoftwareGroup.objects.filter(**filterDict).order_by('-uploadTime')
    else:
        softwareGroup = SoftwareGroup.objects.filter(**filterDict).order_by('-uploadTime').filter(
            Q(user=user) | Q(groupUserType='2', isOnline=True))
    totalNum = len(softwareGroup)
    result = softwareGroup[min(totalNum, (requestParam['page'] - 1) * requestParam['maxItem']): min(totalNum,
                                                                                                    requestParam[
                                                                                                        'page'] *
                                                                                                    requestParam[
                                                                                                        'maxItem'])]
    groupList = []
    # 临时存储
    for groupItem in result:
        softwareDict = {}
        for softwareVersion in groupItem.software.all():
            if softwareVersion.software.id not in softwareDict.keys():
                tempVersion = []
                versionList = {
                    'versionId': softwareVersion.id,
                    'versionName': softwareVersion.version,
                    'isOnline': softwareVersion.isOnline
                }
                tempVersion.append(versionList)
                softwareItem = {
                    'softwareId': softwareVersion.software.id,
                    'softwareName': softwareVersion.softwareName,
                    'softwareDetail': softwareVersion.updateDetails,
                    'currentVersionDesc': softwareVersion.currentVersionDesc,
                    'version': tempVersion
                }
                softwareDict[softwareVersion.software.id] = softwareItem
            else:
                versionList = {
                    'versionId': softwareVersion.id,
                    'versionName': softwareVersion.version,
                    'isOnline': softwareVersion.isOnline
                }
                softwareDict[softwareVersion.software.id]['version'].append(versionList)
        groupSoftware = []
        for i in softwareDict.keys():
            groupSoftware.append(softwareDict[i])
        item = {
            'groupName': groupItem.groupName,
            'groupId': groupItem.id,
            'userName': groupItem.user.name,
            'uploadTime': groupItem.uploadTime.strftime('%Y-%m-%d %H:%M:%S'),
            'groupDetail': groupItem.describe,
            'groupType': groupItem.groupType,
            'isOnline': groupItem.isOnline,
            'groupSoftware': groupSoftware
        }
        groupList.append(item)
    data = {
        'code': 0,
        'msg': 'success',
        'totalNum': totalNum,
        'groupList': groupList,
    }
    logger_request.info(data)
    return JsonResponse(data)


# 查看组详情
def groupDetail(request, *args, **kwargs):
    """
       url: '/software/groupdetail/',
        method: 'post',
        inputData: {
            token: data.token, // 用户的秘钥
            groupId: data.groupId,//组id
        },
        resData: {
            'code': null,// 标志返回状态、0：成功，1：失败
            'msg': null,// 返回消息
            'groupName': null,//服务名称
            'userName': null,//编组用户
            'uploadTime': null,//组上传时间
            'groupDetail': null,//组描述
            'groupType': null,//编排方式
            'planName': null,//部署方案名称
            'planContent': null,//部署方案内容
            'isOnline'： null
            'groupStatus': null
            'groupSoftware': [{//编组包含的软件
                'softwareId': null,//软件id
                'softwareName': null,//软件名称
                'softwareDetail': null,//最新版本的描述
                'version': [{'versionName': null, 'versionId': null, 'ratio': null，'isOnline': 0,1}],//编组时每个软件选择的版本,ratio为空传''
            }],
        }
    }

    """
    form = request.checkForm
    requestParam = form.cleaned_data
    logger_request.info(requestParam)

    user = datacheck.getUser(requestParam["token"])
    softwareGroup = SoftwareGroup.objects.filter(pk=requestParam['groupId'])
    softwareGroupItem = softwareGroup[0]
    groupSoftware = []
    if user.userType in ['1', '2', '3']:
        softwareDict = {}
        try:
            ratio = json.loads(softwareGroupItem.ratio)
            ratioTemp = 0
        except Exception as e:
            data = {
                'code': 1,
                'msg': 'loads error',
            }
            logger_request.info(data)
            return JsonResponse(data)
        for softwareVersion in softwareGroupItem.software.all():
            for dicte in ratio:
                if softwareVersion.software.id in dicte.values():
                    for version in dicte['softwareVersion']:
                        if version['id'] == softwareVersion.id:
                            ratioTemp = version['ratio']
            if softwareVersion.software.id not in softwareDict.keys():
                tempVersion = []
                versionList = {
                    'versionId': softwareVersion.id,
                    'versionName': softwareVersion.version,
                    'isOnline': softwareVersion.isOnline,
                    'ratio': ratioTemp
                }
                tempVersion.append(versionList)
                softwareItem = {
                    'softwareId': softwareVersion.software.id,
                    'softwareName': softwareVersion.softwareName,
                    'softwareDetail': softwareVersion.updateDetails,
                    'currentVersionDesc': softwareVersion.currentVersionDesc,
                    'version': tempVersion
                }
                softwareDict[softwareVersion.software.id] = softwareItem
            else:
                versionList = {
                    'versionId': softwareVersion.id,
                    'versionName': softwareVersion.version,
                    'isOnline': softwareVersion.isOnline,
                    'ratio': ratioTemp
                }
                softwareDict[softwareVersion.software.id]['version'].append(versionList)
        for i in softwareDict.keys():
            groupSoftware.append(softwareDict[i])
    data = {
        'code': 0,
        'msg': 'success',
        'groupName': softwareGroupItem.groupName,
        'userName': softwareGroupItem.user.name,
        'uploadTime': softwareGroupItem.uploadTime.strftime('%Y-%m-%d %H:%M:%S'),
        'groupDetail': softwareGroupItem.describe,
        'groupType': softwareGroupItem.groupType,
        'groupStatus': not softwareGroupItem.isActive,
        'planName': softwareGroupItem.planName,
        'planContent': softwareGroupItem.planContent,
        'isOnline': softwareGroupItem.isOnline,
        'groupSoftware': groupSoftware
    }
    logger_request.info(data)
    return JsonResponse(data)


# 操作
def groupOperate(request, *args, **kwargs):
    """
         url: '/software/groupoperate/',
        method: 'post',
        inputData: {
            token: data.token, // 用户的秘钥
            groupId: data.groupId,//
            operate: data.operate,//0:删除 1：恢复 2、上线 3、下线
        },
        resData: {
            'code': null,// 标志返回状态、0：成功，1：失败
            'msg': null,// 返回消息'success'
        }
    """
    form = request.checkForm
    requestParam = form.cleaned_data
    logger_request.info(requestParam)
    # print(requestParam)
    user = datacheck.getUser(requestParam["token"])
    #  userType
    if user.userType == '2':
        group = SoftwareGroup.objects.filter(pk=requestParam['groupId'])
        groupItem = group[0]
        # 0:删除 1：恢复 2、上线 3、下线
        if requestParam['operate'] == '0':
            pass
            groupItem.isActive = 0
        elif requestParam['operate'] == '1':
            pass
            groupItem.isActive = 1
        elif requestParam['operate'] == '2':
            pass
            groupItem.isOnline = 1
        elif requestParam['operate'] == '3':
            groupItem.isOnline = 0
        else:
            data = {
                'code': 1,
                'msg': 'operate Error',
            }
            logger_request.info(data)
            return JsonResponse(data)
        groupItem.save()
    else:
        pass
    data = {
        'code': 0,
        'msg': 'success',
    }
    logger_request.info(data)
    return JsonResponse(data)


# 服务编组
def groupServiceOperate(request, *args, **kwargs):
    """
        url: '/software/groupserviceoperate/',
        method: 'post',
        inputData: {
            token: data.token, // 用户的秘钥
            groupName: data.groupName,//组名称
            groupDetail: data.groupDetail,//组描述
            category: data.category,//0：软件自由编排，1：能力分组，2：能力预案，3用户订阅
            planName: data.planName,//方案名称，可为''
            planContent: data.planContent,//方案内容，可为空''
            //选择的软件及版本设置
            selectSoftware: data.selectSoftware,
            //例子:JSON类型 [{'softwareId':1,'softwareVersion':[{'id':1,'ratio':0.5},{'id':2,'ratio':0.2},{...}]},{...}]
            //ratio为某个软件版本的灰度测试比例，用户设置则传数形，不设置传''
        },
        resData: {
            'code': null,// 标志返回状态、0：成功，1：失败
            'msg': null,// 返回消息'success'
        }
    """
    form = request.checkForm
    requestParam = form.cleaned_data
    logger_request.info(requestParam)
    # print(requestParam)
    user = datacheck.getUser(requestParam["token"])
    # userType
    # admin store 编组
    if user.userType == '2' or user.userType == '3':
        softwareGroup = SoftwareGroup.objects.create(
            user=user,
            groupName=requestParam["groupName"],
            groupType=requestParam["category"],
            describe=requestParam["groupDetail"],
            planName=requestParam["planName"],
            planContent=requestParam["planContent"],
            groupUserType=user.userType
        )
        # admin 灰度测试
        if user.userType == '2':
            softwareGroup.ratio = requestParam['selectSoftware']
            softwareGroup.save()
        else:
            softwareGroup.ratio = json.dumps('')
            softwareGroup.save()
        selectSoftware1 = json.loads(requestParam['selectSoftware'])
        isBrowse = set()
        # isDownload = set()
        for software in selectSoftware1:
            if 'softwareId' in software:
                if 'softwareVersion' in software:
                    for softwareVersion in software['softwareVersion']:
                        if 'id' in softwareVersion:
                            softwareVersion = SoftwareVersion.objects.filter(pk=softwareVersion['id'])
                            softwareVersionItem = softwareVersion[0]
                            softwareGroup.software.add(softwareVersionItem)
                            for company in softwareVersionItem.isBrowse.all():
                                isBrowse.add(company.id)
                            # for company in softwareVersionItem.isDownload.all():
                            #     isDownload.add(company.id)
                        else:
                            data = {
                                'code': 1,
                                'msg': 'Id None Error',
                            }
                            logger_request.info(data)
                            return JsonResponse(data)
                else:
                    data = {
                        'code': 1,
                        'msg': 'softwareVersion None Error',
                    }
                    logger_request.info(data)
                    return JsonResponse(data)
            else:
                data = {
                    'code': 1,
                    'msg': 'SoftwareId None Error',
                }
                logger_request.info(data)
                return JsonResponse(data)
        # for isDownloadId in isDownload:
        #     softwareGroup.isDownload.add(isDownloadId)
        for isBrowseId in isBrowse:
            softwareGroup.isBrowse.add(isBrowseId)
    else:
        data = {
            'code': 1,
            'msg': 'userType Error',
        }
        logger_request.info(data)
        return JsonResponse(data)
    data = {
        'code': 0,
        'msg': 'success',
    }
    logger_request.info(data)
    return JsonResponse(data)


# 编组下载
def groupDownLoad(request, *args, **kwargs):
    """
          url: '/software/groupDownLoad/',
          method: 'post',
          inputData: {
              token: data.token, // 用户的秘钥
              groupId: data.groupId,//组id
          },
          resData: {
              'code': null,// 标志返回状态、0：成功，1：失败
              'msg': null,// 返回消息'success'
              'url': null,//
          }
      """
    form = request.checkForm
    requestParam = form.cleaned_data
    logger_request.info(requestParam)

    user = datacheck.getUser(requestParam["token"])
    #  userType
    # userType = user.userType
    softwareGroup = SoftwareGroup.objects.filter(pk=requestParam['groupId'])
    if softwareGroup.exists():
        softwareGroupItem = softwareGroup[0]
        # get softwareVersion
        softwareVersionList = softwareGroupItem.software.all()
        softwareVersionDict = {}
        flag = 1
        for softwareVersionItem in softwareVersionList:
            order = SoftwareOrder.objects.filter(softwareVersion=softwareVersionItem,
                                                 orderType='1',
                                                 user=user,
                                                 isExamine=True,
                                                 # orderUpState='0'
                                                 ).order_by('-createTime')
            limit = False
            if order.exists():
                for i in order:
                    if i.isDownload and softwareVersionItem.deliveryType in ["3", "0"]:
                        limit = True
                        break

            if softwareVersionItem.deliveryType == '3' or limit:
                fileDict = {
                    'DataID': {},
                    'FileID': {}
                }
                # DataList = {}
                # fileList = {}

                fileDict['softwareName'] = softwareVersionItem.softwareName

                softwareVersionItemFileList = softwareVersionItem.file.all()
                for fileItem in softwareVersionItemFileList:
                    # fileList['fileID'] = fileItem.id
                    fileList = {}
                    fileList['filePath'] = fileItem.filePath
                    fileList['fileName'] = fileItem.fileName
                    fileDict["FileID"][fileItem.id] = fileList

                softwareDataList = SoftwareData.objects.filter(softwareVersion=softwareVersionItem)
                for dataFile in softwareDataList:
                    # DataList['id'] = dataFile.file.id
                    DataList = {}
                    DataList['filePath'] = dataFile.file.filePath
                    DataList['fileName'] = dataFile.file.fileName
                    fileDict['DataID'][dataFile.file.id] = DataList
                softwareVersionDict[softwareVersionItem.id] = fileDict
                if softwareVersionItem.deliveryType == '3':
                    latest = softwareVersionItem.file.all().order_by("-createTime")
                    if latest.exists():
                        createOrder(softwareVersionItem.id, user.id, softwareVersionItem.deliveryType, orderType='1',
                                    groupId=requestParam['groupId'], softFileId=latest[0].id)
                    else:
                        createOrder(softwareVersionItem.id, user.id, softwareVersionItem.deliveryType, orderType='1',
                                    groupId=requestParam['groupId'], softFileId="")
            else:
                flag = 0
                order = SoftwareOrder.objects.filter(softwareVersion=softwareVersionItem,
                                                     orderType='1',
                                                     user=user,
                                                     isExamine=False,
                                                     orderUpState='0'
                                                     ).order_by('-createTime')
                if not order.exists():
                    latest = softwareVersionItem.file.all().order_by("-createTime")
                    if latest.exists():
                        createOrder(softwareVersionItem.id, user.id, softwareVersionItem.deliveryType, orderType='1',
                                    groupId=requestParam['groupId'], softFileId=latest[0].id)
                    else:
                        createOrder(softwareVersionItem.id, user.id, softwareVersionItem.deliveryType, orderType='1',
                                    groupId=requestParam['groupId'], softFileId="")
        # pprint(softwareVersionDict)
        # pdb.set_trace()
        if requestParam['isUrl']:
            code, msg, fileList = tarSaveToDataBase(softwareVersionDict, requestParam['token'])
            if code == 0:
                isValid, msg = download(fileList[0], "file", fileList[1])
                if isValid:
                    data = {
                        'code': 0,
                        'msg': 'success',
                        'url': msg,
                        'state': flag
                    }
                    logger_request.info(data)
                    return JsonResponse(data)
                else:
                    data = {
                        'code': 1,
                        'msg': 'Error',
                        'url': '',
                        'state': flag
                    }
                    logger_request.info(data)
                    return JsonResponse(data)
            else:
                data = {
                    'code': 1,
                    'msg': msg,
                    'url': '',
                    'state': flag
                }
                logger_request.info(data)
                return JsonResponse(data)
        else:
            data = {
                'code': 0,
                'msg': "success",
                'url': '',
                'state': flag
            }
            logger_request.info(data)
            return JsonResponse(data)
    else:
        data = {
            'code': 1,
            'msg': 'Error',
            'url': '',
            'state': ""
        }
        logger_request.info(data)
        return JsonResponse(data)
